package com.zhang;

import com.zhang.common.config.GlobalConfig;
import com.zhang.handler.HttpNotifyHandler;
import com.zhang.handler.HttpServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 监听来的所有的http请求
 * @author 98265
 */
public class HttpServer {
    /**
     * 合并消息的最大长度
     */
    private final static int maxContentLen = Integer.MAX_VALUE;
    /**
     * http服务绑定的端口
     */
    private int port;

    /**
     * 构造方法
     */
    public HttpServer() {
        this.port = GlobalConfig.props.getInt("httpPort");
    }

    /**
     *  boss线程组
     */
    private EventLoopGroup bossGroup = new NioEventLoopGroup();
    /**
     *  work线程组
     */
    private EventLoopGroup workGroup = new NioEventLoopGroup();

    /**
     * 引导启动类
     */
    private ServerBootstrap b = new ServerBootstrap();

    /**
     *  日志对象
     */
    static private Logger log = LoggerFactory.getLogger(HttpServer.class);
    /**
     * 开启http服务
     */
    public void startHttpServer(){
        try {
            b.group(bossGroup,workGroup);
            b.channel(NioServerSocketChannel.class);
            b.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    //请求解码器
                    ch.pipeline().addLast("httpDecoder",new HttpRequestDecoder());

                    //来请求了  应该先让代理客户端连接真实服务器先
                    ch.pipeline().addLast("httpNotify",new HttpNotifyHandler());
                    //合并请求头 请求行 请求内容
                    ch.pipeline().addLast("httpObject",new HttpObjectAggregator(2 * 1024 * 1024));
                    //处理请求
                    ch.pipeline().addLast("httpHandler",new HttpServerHandler());
                }
            });

            /**
             * 绑定端口
             */
            ChannelFuture future = b.bind(port).addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if(future.isSuccess()){
                        log.info("httpServer启动成功 端口是{}",port);
                    }else{
                        log.error("httpServer启动失败 端口是{}",port);
                    }
                }
            });

            /**
             * 监听退出
             */
            future.channel().closeFuture().addListener((channelFuture)->{
                log.info("等待httpServer服务退出");
                bossGroup.shutdownGracefully();
                workGroup.shutdownGracefully();
            });

        }catch (Exception e){
            log.error("startHttpServer失败 error = {}" ,e);
        }
    }
}
